<template>
  <div class="bigDataCase">
    <div class="info">
      <el-button plain type="primary" @click="addArticle" style="margin-right: 10px" v-loading="addLoading" :disabled="tableData.length > 0 || loading">添加假数据(执行一次)100000</el-button>
      <p>总数据: {{tablePage.totalResult}}  条</p>
      <p style="margin-left: 10px;color: rgb(156 156 156)">懒加载（滚动条到底部加载下一次数据） + 虚拟滚动 + 界面可见区域实时更新 + 展开行</p>
    </div>
    <div class="table">
      <vxe-table
          border="outer"
          round
          stripe
          height="auto"
          auto-resize
          show-overflow
          ref="xTable"
          row-id="listId"
          size="mini"
          :scroll-y="{gt: 0,oSize: 5}"
          :loading="loading"
          :row-config="{keyField: 'listId', isCurrent: true, isHover: true, height: '42'}"
          :checkbox-config="{reserve: true, trigger: 'row',checkField: 'checked'}"
          :expand-config="expandCfg"
          :data="tableData"
          @scroll="scroll"
          @sort-change="sortChange">
        <vxe-column type="checkbox" width="60"></vxe-column>
        <vxe-column field="listId" title="listId" width="150"></vxe-column>
        <vxe-column v-for="(item) in 2" :field="'attr' + item" :title="'attr' + item" sortable :width="item !== 1 ? '30%' : 'auto' "></vxe-column>
        <vxe-column type="expand" width="80" title="操作">
          <template #default="{row}">
            <div>
              详情
            </div>
          </template>
          <template #content="{ row, rowIndex }">
            <div style="width: 100%;height: 100%;padding: 20px 50px">
              <div style="width: 100%;border: 1px solid #efefef;padding: 16px">
                <p v-for="(item) in row">{{ item }}</p>
              </div>
            </div>
          </template>
        </vxe-column>
      </vxe-table>
    </div>
  </div>
</template>

<script setup>
import {computed, onMounted, onUnmounted, ref} from "vue";
import {httpRequest} from "@/untils/httpRequest.ts";
import store from "@/store/index";
import $ from 'jquery'
import {ElMessage} from "element-plus";

let loopTimer = ref(null)
let xTable = ref(null)
let loading = ref(false)
let addLoading = ref(false)
let sortCfg = ref({
  order: '',
  property: ''
})
let tablePage = ref({
  currentPage: 1,
  pageSize: 50,
  totalResult: 0
})
const expandToggleMethod = ({expanded, row}) => {
  if (!expanded) return
  console.log('展开')
  return true
}
let expandCfg = ref({
  showIcon: true,
  accordion: true,
  reserve: true,
  iconOpen: 'iconfont i-arrow-up- c_3399ff',
  iconClose: 'iconfont i-arrow-down- c_3399ff',
  toggleMethod: expandToggleMethod
})
let tableData = ref([])
const additionalData = _.debounce((scrollTop, scrollHeight)=>{
  let screenHeight = $('.vxe-table--body-wrapper')[0]?.style?.height?.split('px')[0]
  if ((scrollTop + Number(screenHeight)) > (scrollHeight - 36)) {
    if (tablePage.value.currentPage < Math.ceil(tablePage.value.totalResult / 50)) {//当前页数小于总页数就请求
      loading.value = true
      tablePage.value.currentPage ++
      let params = {
        currentPage: tablePage.value.currentPage,
        pageSize: 50,
        property: sortCfg.value.property,
        order: sortCfg.value.order
      };
      httpRequest("post", "/component/getArticle", null, params, "proxy").then(res => {
        if (res?.data?.code === 200) {
          tableData.value = tableData.value.concat(res?.data?.data?.list || [])
        }
      }).finally(()=>{
        loading.value = false
      });
    }
  }
},200)

const clearScrollLoop = _.debounce(() => {
  //停止滚动打开循环
  loopGetData()
}, 800)

const scroll = ({scrollTop, scrollHeight}) => {
  //滚动时关闭循环
  if (loopTimer.value) clearTimeout(loopTimer.value)
  additionalData(scrollTop, scrollHeight)
  clearScrollLoop()
}
const sortChange = ({ property, order }) => {
  sortCfg.value.order = order;
  sortCfg.value.property = order ? property : null;
  initView();
}
// 实时更新列表可见区域数据
const loopGetData = () => {
  return new Promise((resolve, reject) => {
    let showRows = $('.vxe-table--body .vxe-body--row')
    showRows = Array.prototype.slice.call(showRows)
    // 需要实时更新的ids
    let loopIds = showRows.map(row => row.getAttribute('rowid'))
    let params = {
      loopIds: loopIds
    };
    httpRequest("post", "/component/getArticle", null, params, "proxy", false).then(res => {
      if (res?.data?.code === 200) {
        let list = res?.data?.data?.list || []
        list.forEach((item,index) => {
          item.attr1 = item.attr1 + ',可视区实时获取' + Math.random() * 10
        })
        tableData.value.forEach(row => {
          list.forEach(item => {
            if (row.listId === item.listId) _.assign(row, item)
          })
        })
        if (loopTimer.value) clearTimeout(loopTimer.value)
        loopTimer.value = setTimeout(()=> loopGetData(), 2000)
        resolve()
      }
    }).catch((e) => {
      reject(e)
    })
  })
}
const initView = () => {
  return new Promise((resolve, reject) => {
    loading.value = true
    let params = {
      currentPage: 1,
      pageSize: 50,
      property: sortCfg.value.property,
      order: sortCfg.value.order
    };
    httpRequest("post", "/component/getArticle", null, params, "proxy").then(res => {
      if (res?.data?.code === 200) {
        tableData.value = res.data.data.list
        tablePage.value.totalResult = res.data.data.total
        resolve()
      } else {
        reject()
      }
    })
  })
}
const addArticle = () => {
  let params = {
    loopCount: 100000
  }
  addLoading.value = true
  httpRequest("post", "/component/addArticle", null, params, "proxy").then(res => {
    addLoading.value = false
    if (res ?.data?.code === 200) {
      ElMessage.success(res?.data?.msg)
    } else {
      ElMessage.error(res?.data?.msg)
    }
  });
}

onUnmounted(()=>{
  clearTimeout( loopTimer.value)
  loopTimer.value = null
})
onMounted(()=>{
  initView().then(()=>{
    loopGetData()
  }).finally(()=>{
    loading.value = false
  })
})

</script>

<style scoped lang="less">
.bigDataCase {
  width: 100%;
  height: 100%;
  .info {
    width: 100%;
    height: 32px;
    display: flex;
    align-items: center;
  }
  .table {
    margin-top: 16px;
    width: 100%;
    height: calc(100% - 48px);
  }

}
</style>
<style>
.bigDataCase .col--expand > div {
  display: flex;
  align-items: center;
}
.c_3399ff {
  color: #3399ff !important;
}
</style>